/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */
package com.ecarx.systemui.plugin.ui.statusbar

import android.car.Car
import android.car.VehicleAreaSeat
import android.car.VehicleAreaType
import android.car.hardware.CarPropertyValue
import android.car.hardware.property.CarPropertyManager
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.core.content.res.ResourcesCompat
import com.ecarx.systemui.plugin.R
import com.ecarx.systemui.plugin.ui.custom.SystemBarButton
import com.ecarx.systemui.plugin.ui.dialog.base.DialogManager
import com.ecarx.systemui.plugin.utils.LogUtils
import com.ecarx.xui.adaptapi.car.vehicle.IWpc
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import vendor.ecarx.xma.automotive.vehicle.V2_0.ChargingStates
import vendor.ecarx.xma.automotive.vehicle.V2_0.ECarXVehicleProperty

/**
 * IWpc.CHARGE_STATE_CHARGING
 * IWpc.CHARGE_STATE_FULLY_CHARGED
 * IWpc.WPC_FUNC_CHARGE_PERCENTAGE
 * IWpc.WPC_FUNC_CHARGE_STATES
 */
class WpcView : SystemBarButton, CarPropertyManager.CarPropertyEventCallback {

    companion object {
        private const val TAG = "WpcView"

        private const val PROP_WPC_FUNC_WORK_MODE: Int = ECarXVehicleProperty.WPC_FUNC_WORK_MODE
        private const val PROP_WPC_FUNC_CHARGE_PERCENTAGE: Int =
            ECarXVehicleProperty.WPC_FUNC_CHARGE_PERCENTAGE
        private const val PROP_WPC_FUNC_CHARGE_STATES: Int =
            ECarXVehicleProperty.WPC_FUNC_CHARGE_STATES
    }

    private var mCarPropertyManager: CarPropertyManager? = null

    private var isWorking: Boolean = false

    // 充电状态
    private var mChargingStatus: Int = -1

    constructor(context: Context?) : this(context!!, null) {}
    constructor(context: Context?, attrs: AttributeSet?) : this(context!!, attrs, 0) {}
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context!!, attrs, defStyleAttr
    ) {

    }

    override fun getContentDescriptionString(): String {
        return "WpcView"
    }

    override fun initView() {
        super.initView()

        setImageDrawable(
            ResourcesCompat.getDrawable(
                resources, R.drawable.ic_wpc_80, context.theme
            )
        )
        visibility = View.GONE

        setOnClickListener { v: View? ->
            val locations = IntArray(2)
            getLocationOnScreen(locations)
            val location = (locations[0] - resources.getDimension(R.dimen.dp_710) / 2).toInt()
            DialogManager.getDialogManager().showWpcDialog(context, location, getStatus())
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        registerVHALSignal()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        unregisterVHALSignal()
        DialogManager.getDialogManager().wpcDialog?.dismiss()
    }


    private fun getStatus(): Int {
        return mChargingStatus
    }

    private fun registerVHALSignal() {

        // 监听 WPC 状态
        CoroutineScope(Dispatchers.IO).launch {
            Car.createCar(context, null, 10000) { car, ready ->
                if (ready) {
                    LogUtils.d(TAG, "registerVHALSignal with CarService")
                    mCarPropertyManager =
                        car?.getCarManager(Car.PROPERTY_SERVICE) as CarPropertyManager

                    mCarPropertyManager?.registerCallback(
                        this@WpcView, PROP_WPC_FUNC_WORK_MODE, CarPropertyManager.SENSOR_RATE_NORMAL
                    )
                    mCarPropertyManager?.registerCallback(
                        this@WpcView,
                        PROP_WPC_FUNC_CHARGE_PERCENTAGE,
                        CarPropertyManager.SENSOR_RATE_NORMAL
                    )
                    mCarPropertyManager?.registerCallback(
                        this@WpcView,
                        PROP_WPC_FUNC_CHARGE_STATES,
                        CarPropertyManager.SENSOR_RATE_NORMAL
                    )

                    try {
                        var areaType =
                            VehicleAreaSeat.SEAT_ROW_1_LEFT or VehicleAreaSeat.SEAT_ROW_1_RIGHT or VehicleAreaSeat.SEAT_ROW_2_LEFT or VehicleAreaSeat.SEAT_ROW_2_RIGHT or VehicleAreaSeat.SEAT_ROW_2_CENTER
                        val isClose = mCarPropertyManager?.getBooleanProperty(
                            PROP_WPC_FUNC_WORK_MODE, areaType
                        ) == true
                        val batteryPercentage = mCarPropertyManager?.getFloatProperty(
                            PROP_WPC_FUNC_CHARGE_PERCENTAGE, areaType
                        )
                        showIcon(isClose, (batteryPercentage!! * 100).toInt())
                    } catch (throwable: Throwable) {
                        throwable.printStackTrace()
                    }
                } else {
                    LogUtils.e(TAG, "registerVHALSignal: failed with CarService not ready")
                }
            }
        }

    }

    private fun unregisterVHALSignal() {
        mCarPropertyManager?.unregisterCallback(this)
    }

    override fun onChangeEvent(carPropertyValue: CarPropertyValue<*>?) {
        LogUtils.d(TAG, "onChangeEvent() called with: carPropertyValue = $carPropertyValue")
        if (carPropertyValue?.status == CarPropertyValue.STATUS_AVAILABLE) {
            if (carPropertyValue.propertyId == PROP_WPC_FUNC_WORK_MODE) {
                isWorking = carPropertyValue.value as Boolean
                var areaType =
                    VehicleAreaSeat.SEAT_ROW_1_LEFT or VehicleAreaSeat.SEAT_ROW_1_RIGHT or VehicleAreaSeat.SEAT_ROW_2_LEFT or VehicleAreaSeat.SEAT_ROW_2_RIGHT or VehicleAreaSeat.SEAT_ROW_2_CENTER
                mChargingStatus = mCarPropertyManager?.getIntProperty(
                    PROP_WPC_FUNC_CHARGE_STATES, areaType
                )!!
                if (!isWorking) {
                    showIcon(isWorking, -1)
                } else {
                    showIconWithChangeStatus(mChargingStatus)
                }

            } else if (carPropertyValue.propertyId == PROP_WPC_FUNC_CHARGE_PERCENTAGE) {
                showIcon(isWorking, (carPropertyValue.value as Float * 100).toInt())
            } else if (carPropertyValue.propertyId == PROP_WPC_FUNC_CHARGE_STATES) {
                var chargingStatus = carPropertyValue.value as Int
                mChargingStatus = chargingStatus
                showIconWithChangeStatus(chargingStatus)
            }
        } else {
            LogUtils.e(
                TAG,
                "onChangeEvent() with: propertyId = ${carPropertyValue?.propertyId}, not available!"
            )
            if (carPropertyValue?.propertyId == PROP_WPC_FUNC_WORK_MODE || carPropertyValue?.propertyId == PROP_WPC_FUNC_CHARGE_PERCENTAGE || carPropertyValue?.propertyId == PROP_WPC_FUNC_CHARGE_STATES) {
                showIcon(false, -1)
            }
        }
    }

    private fun showIconWithChangeStatus(chargingStatus: Int) {
        LogUtils.e(
            TAG,
            "showIconWithChangeStatus() with: chargingStatus = ${chargingStatus}!"
        )

        if (chargingStatus == ChargingStates.CHARGE_STATE_CHARGING) {
            var areaType =
                VehicleAreaSeat.SEAT_ROW_1_LEFT or VehicleAreaSeat.SEAT_ROW_1_RIGHT or VehicleAreaSeat.SEAT_ROW_2_LEFT or VehicleAreaSeat.SEAT_ROW_2_RIGHT or VehicleAreaSeat.SEAT_ROW_2_CENTER
            var percent = mCarPropertyManager?.getFloatProperty(
                PROP_WPC_FUNC_CHARGE_PERCENTAGE, areaType
            )!!
            // 充电中
            showIcon(isWorking, (percent * 100).toInt())
        } else if (chargingStatus == 5) {
            // 充满电

            showIcon(isWorking, 200)
        } else if (chargingStatus == 1 || chargingStatus == 6 || chargingStatus == 9 || chargingStatus == 11) {
            // 未知，出错
            showIcon(isWorking, -1)
        } else if (chargingStatus == 0) {
            //CHARGE_STATE_OFF  关关闭
            showIcon(false, -1)
        } else if (chargingStatus == 2 or 3) {

            //StandBy or CHARGE_STATE_NO_DEVICE
            showIcon(isWorking, 100)
        } else {
            showIcon(isWorking, -1)
        }
    }

    override fun onErrorEvent(propertyId: Int, areaId: Int) {
        LogUtils.e(TAG, "onErrorEvent() called with: propertyId = $propertyId, areaId = $areaId")
        if (propertyId == PROP_WPC_FUNC_WORK_MODE) {
            isWorking = false
        }
        showIcon(false, -1)
    }

    private fun showIcon(show: Boolean, batteryPercentage: Int) {
        LogUtils.e(
            TAG, "showIcon() called with: show = $show, batteryPercentage = $batteryPercentage"
        )
        CoroutineScope(Dispatchers.Main).launch {
            if (show) {
                visibility = View.VISIBLE
                setImageDrawable(
                    ResourcesCompat.getDrawable(
                        resources, getResId(batteryPercentage), context.theme
                    )
                )
            } else {
                visibility = View.GONE
            }
        }
    }

    private fun getResId(batteryPercentage: Int): Int {
        return if (batteryPercentage < 0) {
            R.drawable.ic_wpc_0
        } else if (batteryPercentage < 20) {
            R.drawable.ic_wpc_10
        } else if (batteryPercentage < 40) {
            R.drawable.ic_wpc_20
        } else if (batteryPercentage < 60) {
            R.drawable.ic_wpc_40
        } else if (batteryPercentage < 80) {
            R.drawable.ic_wpc_60
        } else if (batteryPercentage < 100) {
            R.drawable.ic_wpc_80
        } else if (batteryPercentage == 100) {
            R.drawable.ic_wpc_complete
        } else {
            R.drawable.ic_wpc_100
        }
    }


}